Implementing "Load More on Scroll" in Laravel: A Complete Guide

18 Oct 2024 11:21 PM

In modern web applications, providing a smooth user experience is crucial. One popular feature that enhances user interaction is the "load more on scroll" functionality. This allows users to dynamically load content without refreshing the page, making it feel seamless and engaging. In this post, we’ll walk through the steps to implement this feature in a Laravel application using jQuery and Ajax.

Prerequisites

Before we begin, make sure you have the following:

  • A basic understanding of Laravel.
  • A local development environment set up for Laravel.
  • Composer installed.

Step 1: Setting Up Your Laravel Project

If you don’t have a Laravel project set up yet, you can create one using the following command:

composer create-project --prefer-dist laravel/laravel your-project-name

Once your project is set up, navigate to your project directory.

Step 2: Create a Model and Migration

For our example, let’s assume we want to display a list of blog posts. First, create a model and a migration file:

php artisan make:model Post -m

In the migration file located in database/migrations, define the structure for your posts table:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Next, run the migration to create the table:

php artisan migrate

Step 3: Seed Your Database with Sample Data

To test our implementation, let’s seed some sample posts into the database. Create a new seeder:

php artisan make:seeder PostSeeder

In the PostSeeder.php, add the following code to generate sample data:

public function run()
{
    \App\Models\Post::factory()->count(50)->create();
}

Now, run the seeder:

php artisan db:seed --class=PostSeeder

Step 4: Create a Controller

Next, we’ll create a controller that will handle fetching and displaying the posts:

php artisan make:controller PostController

In the PostController.php, implement the following methods:

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::paginate(5); // Load 5 posts at a time
        return view('posts.index', compact('posts'));
    }

    public function loadMore(Request $request)
    {
        if ($request->ajax()) {
            $posts = Post::paginate(5);
            return view('posts.load_more', compact('posts'))->render();
        }
    }
}

Step 5: Define Your Routes

In your routes/web.php, define the routes for displaying posts and handling Ajax requests:

use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts/load-more', [PostController::class, 'loadMore']);

Step 6: Create the Blade Views

Now, let’s create the main view where our posts will be displayed. Create a file at resources/views/posts/index.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load More on Scroll</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div id="post-container">
        @foreach($posts as $post)
            <div class="post">
                <h2>{{ $post->title }}</h2>
                <p>{{ $post->content }}</p>
            </div>
        @endforeach
    </div>
    <div class="load-more">
        <button id="load-more-btn">Load More</button>
    </div>

    <script>
        let page = 1;

        $('#load-more-btn').click(function() {
            page++;
            $.ajax({
                url: '/posts/load-more',
                type: 'POST',
                data: {
                    _token: '{{ csrf_token() }}',
                    page: page,
                },
                success: function(data) {
                    if(data) {
                        $('#post-container').append(data);
                    } else {
                        $('#load-more-btn').hide();
                    }
                }
            });
        });

        // Optional: Load more on scroll
        $(window).scroll(function() {
            if($(window).scrollTop() + $(window).height() >= $(document).height()) {
                $('#load-more-btn').click();
            }
        });
    </script>
</body>
</html>

Step 7: Create the Load More Blade View

Create a new Blade view file at resources/views/posts/load_more.blade.php for loading additional posts:

@foreach($posts as $post)
    <div class="post">
        <h2>{{ $post->title }}</h2>
        <p>{{ $post->content }}</p>
    </div>
@endforeach

Step 8: Testing Your Implementation

Now that everything is set up, run your Laravel application:

php artisan serve

Visit http://localhost:8000/posts. You should see your initial list of posts, and clicking the "Load More" button (or scrolling down) will fetch additional posts without reloading the page.

Conclusion

Congratulations! You’ve successfully implemented a "load more on scroll" feature in your Laravel application. This dynamic content loading not only improves user experience but also optimizes performance by loading data in chunks.

Feel free to customize this implementation further by adding animations, loading indicators, or additional features based on your project needs. Happy coding, and let me know if you have any questions or feedback!

1
11